package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.mapper.ProductMapper;
import com.spzx.product.service.*;
import com.spzx.product.api.domain.Product;
import com.spzx.product.api.domain.ProductDetails;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuStock;
import com.spzx.product.api.domain.vo.ProductVo;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Arrays;
import java.util.List;

@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
    @Resource
    private BrandService brandService;
    @Resource
    private CategoryService categoryService;
    @Resource
    private ProductSkuService productSkuService;
    @Resource
    private SkuStockService skuStockService;
    @Resource
    private ProductDetailsService productDetailsService;

    @Override
    public List<Product> getProductList(Product product) {
        return baseMapper.getProductList(product);
    }

    @Override
    public ProductVo getProductById(Long id) {
        Product product = getById(id);
        product.setBrandName(brandService.getById(product.getBrandId()).getName());
        product.setCategory1Name(categoryService.getById(product.getCategory1Id()).getName());
        product.setCategory2Name(categoryService.getById(product.getCategory2Id()).getName());
        product.setCategory3Name(categoryService.getById(product.getCategory3Id()).getName());

        List<ProductSku> list = productSkuService.list(new LambdaQueryWrapper<ProductSku>().eq(ProductSku::getProductId, id));
        if (CollectionUtils.isEmpty(list)) {
            for (ProductSku productSku : list) {
                SkuStock skuStock = skuStockService.getOne(new LambdaQueryWrapper<SkuStock>().eq(SkuStock::getSkuId, productSku.getId()));
                productSku.setStockNum(skuStock.getTotalNum());
                productSku.setSaleNum(skuStock.getSaleNum());
            }
        }

        String imageUrls = productDetailsService.getById(id).getImageUrls();
        List<String> detailsImageUrlList = null;
        if (imageUrls != null) {
            detailsImageUrlList = Arrays.asList(imageUrls.split(","));
        }
        ProductVo productVo = new ProductVo();
        BeanUtils.copyProperties(product, productVo);
        productVo.setProductSkuList(list);
        productVo.setDetailsImageUrlList(detailsImageUrlList);
        return productVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdateProduct(@RequestBody ProductVo productVo) {
        checkProductUnique(productVo);

        saveOrUpdate(productVo);

        List<ProductSku> productSkuList = productVo.getProductSkuList();
        if (!CollectionUtils.isEmpty(productSkuList)) {
            for (int i = 0; i < productSkuList.size(); i++) {
                ProductSku productSku = productSkuList.get(i);
                productSku.setProductId(productVo.getId());
                productSku.setSkuCode(productVo.getId() + "-" + i);
                productSku.setSkuName(productVo.getName() + productSku.getSkuSpec());
                productSku.setCreateBy(productVo.getCreateBy());
                productSku.setUpdateBy(productVo.getUpdateBy());
                productSkuService.saveOrUpdate(productSku);

                SkuStock skuStock = skuStockService.getOne(new LambdaQueryWrapper<SkuStock>().eq(SkuStock::getSkuId, productSku.getId()));
                if (skuStock == null) {
                    skuStock = new SkuStock();
                    skuStock.setSkuId(productSku.getId());
                    skuStock.setSaleNum(0);
                    skuStock.setLockNum(0);
                    skuStock.setTotalNum(productSku.getStockNum());
                    skuStock.setAvailableNum(productSku.getStockNum());
                    skuStock.setCreateBy(productVo.getCreateBy());
                } else {
                    skuStock.setTotalNum(productSku.getStockNum());
                    skuStock.setAvailableNum(productSku.getStockNum() - skuStock.getLockNum());
                    skuStock.setUpdateBy(productVo.getUpdateBy());
                }
                skuStockService.saveOrUpdate(skuStock);
            }
        }

        List<String> detailsImageUrlList = productVo.getDetailsImageUrlList();
        if (!CollectionUtils.isEmpty(detailsImageUrlList)) {
            String imageUrls = StringUtils.join(",", detailsImageUrlList);
            ProductDetails productDetails = new ProductDetails();
            productDetails.setProductId(productVo.getId());
            productDetails.setImageUrls(imageUrls);
            productDetails.setCreateBy(productVo.getCreateBy());
            productDetails.setUpdateBy(productVo.getUpdateBy());
            productDetailsService.saveOrUpdate(productDetails);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteProductByIds(Long id) {
        //删除基本信息
        removeById(id);
        productDetailsService.remove(new LambdaQueryWrapper<ProductDetails>().eq(ProductDetails::getProductId, id));
        List<Long> skuIds = productSkuService.list(new LambdaQueryWrapper<ProductSku>().eq(ProductSku::getProductId, id).select(ProductSku::getId)).stream().map(ProductSku::getId).toList();
        productSkuService.removeBatchByIds(skuIds);
        skuStockService.remove(new LambdaQueryWrapper<SkuStock>().in(SkuStock::getSkuId, skuIds));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateProductStatus(Long id, Integer status) {
        update(new LambdaUpdateWrapper<Product>().eq(Product::getId, id).set(Product::getStatus, status).set(Product::getUpdateBy, SecurityUtils.getUsername()));
        List<Long> skuIds = productSkuService.list(new LambdaQueryWrapper<ProductSku>().eq(ProductSku::getProductId, id).select(ProductSku::getId)).stream().map(ProductSku::getId).toList();

        productSkuService.update(new LambdaUpdateWrapper<ProductSku>().in(ProductSku::getId, skuIds).set(ProductSku::getStatus, status));
        skuStockService.update(new LambdaUpdateWrapper<SkuStock>().in(SkuStock::getId, skuIds).set(SkuStock::getStatus, status));

        return true;
    }

    private void checkProductUnique(ProductVo productVo) {
        if (productVo.getId() == null) {
            productVo.setCreateBy(SecurityUtils.getUsername());
        } else {
            productVo.setUpdateBy(SecurityUtils.getUsername());
        }
        Product one = baseMapper.selectOne((new LambdaQueryWrapper<Product>().eq(Product::getName, productVo.getName()).eq(Product::getBrandId, productVo.getBrandId())));
        Long count = baseMapper.selectCount((new LambdaQueryWrapper<Product>().eq(Product::getName, productVo.getName()).eq(Product::getBrandId, productVo.getBrandId())));
        if (count > 0) {
            throw new ServiceException("商品名称已存在");
        }
    }

}




